import React, { useState, forwardRef, useImperativeHandle } from 'react';
import style from './index.less';
import { Checkbox, Input, Spin, Table } from 'antd';
import { useSetState, useUpdateEffect, useMount, useUpdate, useDebounce } from 'ahooks';
import classNames from 'classnames';
import update from 'immutability-helper';
import _ from 'lodash';
import { DndProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
// components
import { TRDefault } from '@/components';
import { default as DragableBodyRow } from '../DragableBodyRow';
import { DeleteOutlined, SearchOutlined, SwapOutlined } from '@/utils/antdIcons';
import {
  get_checkbox_ids,
  operation_Type,
  delete_menu,
  checkbox_is_checked,
  batch_delete_menu,
  delete_all_checkded_id,
  swapArr,
} from './helper';
import { tableLocale } from '#/components/PageEmpty';

const CheckboxGroup = Checkbox.Group;
const styles = {
  marginLeft: '8px',
};

export default forwardRef(
  (
    {
      checkList = [],
      firstMenuId = '',
      isRoles = false,
      echoLoading = false,
      handleEcho,
      echoList,
      echoType,
      defaultFlag = false,
    },
    ref,
  ) => {
    const [state, setState] = useSetState({
      filterCheckList: [], // 输入框筛选 - 选择列表筛选
      filterCheckMenuList: [], // 选择列表 - 回显列表筛选
      checkedIdList: [], // 选中的id
      checkedSecondMenuList: [], // 右边回显示的值
      indeterminate: false, // 是否显示选中
      checkAll: false, // 是否全选
      loading: false,
    });
    const [checkInput, setCheckInput] = useState('');
    const [checkEcho, setCheckEcho] = useState('');
    const debouncedCheckInput = useDebounce(checkInput, { wait: 500 });
    const debouncedCheckEcho = useDebounce(checkEcho, { wait: 500 });

    useUpdateEffect(() => {
      setState({
        filterCheckList: checkList,
      });
    }, [checkList]);
    // checkbox 筛选
    useUpdateEffect(() => {
      const { checkedIdList } = state;
      const filterArr = _.filter(checkList, (_v) =>
        _v.name.toUpperCase().includes(debouncedCheckInput.toUpperCase()),
      );
      const ids = _.map(filterArr, (_v) => _v.id);
      const checkId = _.intersection(checkedIdList, ids); // 交集，当前刷新出来的，，有没有选中的id
      const isCheck = checkbox_is_checked(checkId, ids);
      setState({
        filterCheckList: debouncedCheckInput ? filterArr : checkList,
        ...isCheck,
      });
    }, [debouncedCheckInput]);

    // 已选的筛选
    useUpdateEffect(() => {
      const _findArr = _.reduce(
        state.checkedSecondMenuList,
        (t, v) => {
          if (v.operationType === operation_Type['delete']) {
            return t;
          } else {
            return [...t, v];
          }
        },
        [],
      );
      const filterArr = _.filter(_findArr, (_v) => _v.name.includes(debouncedCheckEcho));
      setState({
        filterCheckMenuList: debouncedCheckEcho ? filterArr || [] : _findArr || [],
      });
    }, [state.checkedSecondMenuList, debouncedCheckEcho]);

    useUpdateEffect(() => {
      handleEcho && handleEcho(state.checkedSecondMenuList);
    }, [state.checkedSecondMenuList]);

    const components = { body: { row: DragableBodyRow } };

    const moveRow = (dragIndex, hoverIndex) => {
      const { filterCheckMenuList, checkedSecondMenuList } = state;
      const dragRow = filterCheckMenuList[dragIndex];
      const hoverRow = filterCheckMenuList[hoverIndex];
      const sort = swapArr(checkedSecondMenuList, hoverRow.id, dragRow.id);
      const dragNewRow = checkedSecondMenuList[sort.index1];
      setState({
        checkedSecondMenuList: update(checkedSecondMenuList, {
          $splice: [
            [sort.index1, 1],
            [sort.index2, 0, dragNewRow],
          ],
        }),
      });
    };

    useImperativeHandle(ref, () => {
      //获取子组件ref
      return { _changeLoading };
    });

    useUpdate(() => {
      setState({
        loading: echoLoading,
      });
    }, [echoLoading]);

    const _changeLoading = (isBool) => {
      setState({
        loading: isBool,
      });
    };

    useUpdateEffect(() => {
      if (firstMenuId && echoList.length) {
        const _find = _.find(echoList, (_v) => {
          return _v.firstMenuId === firstMenuId;
        });
        const _ids = get_checkbox_ids(_find.secondMenuList);
        setState({
          checkedIdList: _ids,
          checkedSecondMenuList: _find?.secondMenuList || [],
        });
        // 清空输入框
        setCheckEcho('');
        setCheckInput('');
        // 切换一级 菜单 触发
        if (checkList.length && firstMenuId) {
          const isChecked = checkbox_is_checked(_ids, checkList);
          setState({
            indeterminate: isChecked.indeterminate,
            checkAll: isChecked.checkAll,
          });
        }
      }
    }, [firstMenuId]);

    useUpdateEffect(() => {
      let _ids = [];
      if (firstMenuId && echoList.length) {
        const _find = _.find(echoList, (_v) => {
          return _v.firstMenuId === firstMenuId;
        });
        _ids = get_checkbox_ids(_find.secondMenuList);
      }
      if (isRoles) {
        _ids = get_checkbox_ids(echoList);
      }
      const isChecked = checkbox_is_checked(_ids, checkList);
      setState({
        indeterminate: isChecked.indeterminate,
        checkAll: isChecked.checkAll,
      });
    }, [checkList]);

    useMount(() => {
      if (isRoles) {
        const _ids = get_checkbox_ids(echoList);
        setState({
          checkedIdList: _ids,
          checkedSecondMenuList: echoList,
        });
      }
    });

    const onCheckAllChange = (e) => {
      const { checked } = e.target;
      const { checkedSecondMenuList, filterCheckList, checkedIdList } = state;
      const ids = _.map(filterCheckList, (_v) => _v.id); // 当前筛选的id
      const union = _.union(ids, checkedIdList); // 并集
      if (checked) {
        const xor = _.xor(union, checkedIdList); // 差集
        const menuList = filterCheckList.reduce((t, v) => {
          if (xor.includes(v.id))
            return [...t, { ...v, operationType: operation_Type['add'], homePageFlag: false }];
          return t;
        }, []);
        setState({
          checkedSecondMenuList: [...checkedSecondMenuList, ...menuList],
          checkedIdList: union,
          checkAll: checked,
          indeterminate: false,
        });
      } else {
        const realIds = delete_all_checkded_id(filterCheckList); // 获取可以删除的id
        const xor = _.xor(union, realIds);
        const deletaArr = batch_delete_menu(checkedSecondMenuList, realIds); // 删除回显
        const isChecked = checkbox_is_checked(ids, xor);
        setState({
          checkedSecondMenuList: deletaArr,
          checkedIdList: xor,
          ...isChecked,
        });
      }
    };

    const _onChangeCheck = (e) => {
      const { checkedSecondMenuList } = state;
      const { checked, value = '' } = e.target;
      let secMenu = [];
      if (checked) {
        const _secMenu = _.find(checkList, (_v) => _v.id === value);
        const _isFind = _.some(checkedSecondMenuList, (_v) => _v.id === value);
        if (_isFind) {
          secMenu = _.map(checkedSecondMenuList, (_v) => {
            if (_v.id === value) {
              _v.operationType = operation_Type['edit'];
            }
            return _v;
          });
        } else {
          secMenu = [
            ...checkedSecondMenuList,
            { ..._secMenu, operationType: operation_Type['add'], homePageFlag: false },
          ];
        }
      } else {
        secMenu = delete_menu({ arr: checkedSecondMenuList, value });
      }
      const _ids = get_checkbox_ids(secMenu);
      const isChecked = checkbox_is_checked(_ids, checkList);
      setState({
        checkedSecondMenuList: secMenu,
        checkedIdList: _ids,
        ...isChecked,
      });
    };
    const columns = [
      {
        dataIndex: 'name',
        key: 'name',
        width: echoType === 'role' ? '250px' : '220px',
        render: (_, record) => (
          <div className={style.appIcon}>
            <span>{record.name}</span>
          </div>
        ),
      },
      {
        dataIndex: 'action',
        key: 'action',
        align: 'right',
        render: (_, record) => (
          <>
            {echoType === 'secMenu' ? (
              <>
                {record.homePageFlag ? (
                  <a style={{ color: '#18A0FB' }}>已设为首页</a>
                ) : (
                  <>
                    {defaultFlag || record?.saasAdminFlag ? null : (
                      <a
                        style={styles}
                        className={style.recordRight}
                        onClick={() => handleCheck(record.id, 'homePageFlag')}
                      >
                        设为首页
                      </a>
                    )}
                  </>
                )}
                {defaultFlag || record?.saasAdminFlag ? null : (
                  <a style={styles} className={style.recordRight}>
                    <SwapOutlined rotate={90} />
                  </a>
                )}
              </>
            ) : null}
            {defaultFlag || record?.saasAdminFlag ? null : (
              <a
                style={styles}
                className={style.recordRight}
                onClick={() => handleCheck(record.id, 'detele')}
              >
                <DeleteOutlined />
              </a>
            )}
          </>
        ),
      },
    ];

    // 清空
    const handleEmpty = () => {
      const { checkedSecondMenuList, filterCheckMenuList, checkedIdList } = state;
      const ids = _.map(filterCheckMenuList, (v) => v.id); // 当前筛选的id
      const realIds = delete_all_checkded_id(filterCheckMenuList); // 获取可以删除的id
      const inter = _.intersection(realIds, checkedIdList); // 交集
      const xorWith = _.xorWith(checkedIdList, inter); // 差集
      const deleteMenu = batch_delete_menu(checkedSecondMenuList, inter); // 批量删除的菜单
      const isChecked = checkbox_is_checked(xorWith, ids);
      setState({
        checkedIdList: xorWith,
        checkedSecondMenuList: deleteMenu,
        ...isChecked,
      });
    };

    // 回显栏的操作
    const handleCheck = (id, type) => {
      const { checkedSecondMenuList, checkedIdList } = state;
      switch (type) {
        case 'detele':
          const deleteMenu = delete_menu({ arr: checkedSecondMenuList, value: id });
          const idList = _.filter(checkedIdList, (_v) => _v !== id);
          const isChecked = checkbox_is_checked(idList, checkList);
          setState({
            checkedSecondMenuList: deleteMenu,
            checkedIdList: idList,
            indeterminate: isChecked.indeterminate,
            checkAll: isChecked.checkAll,
          });
          break;
        case 'homePageFlag':
          // 二级菜单配置时在同一个应用中只能有1个菜单是“设为首页”
          _.reduce(
            echoList,
            (t, v) => {
              if (v.firstMenuId === firstMenuId) {
                v.secondMenuList = _.map(v.secondMenuList, (vc) => {
                  if (vc.id === id) {
                    vc.homePageFlag = true;
                  } else {
                    vc.homePageFlag = false;
                  }
                  return vc;
                });
              } else {
                v.secondMenuList = _.map(v.secondMenuList, (vt) => {
                  vt.homePageFlag = false;
                  return vt;
                });
              }
              return [...t, v];
            },
            [],
          );
          const mapArr = _.map(checkedSecondMenuList, (_v) => {
            if (id === _v.id) {
              _v.homePageFlag = true;
            } else {
              _v.homePageFlag = false;
            }
            return _v;
          });
          setState({
            checkedSecondMenuList: mapArr,
          });
          break;
        default:
          break;
      }
    };

    const defuatChcek = (item) => {
      const { checkedIdList } = state;
      if (item.saasAdminFlag && checkedIdList.includes(item.id)) return true;
      return false;
    };

    return (
      <Spin spinning={state.loading}>
        <div
          className={classNames(
            style.content,
            echoType === 'secMenu' ? style.contentSecMenu : style.contentRole,
          )}
        >
          <div className={style.boxContent}>
            <div className={style.commonInput}>
              <Input
                placeholder="搜索"
                value={checkInput}
                onChange={(e) => setCheckInput(e.target.value)}
                suffix={<SearchOutlined style={{ fontSize: 14 }} />}
                allowClear
              />
            </div>
            <Checkbox
              indeterminate={state.indeterminate}
              onChange={onCheckAllChange}
              checked={state.checkAll}
              disabled={defaultFlag}
              style={{ padding: '8px 15px 10px' }}
            >
              全部
            </Checkbox>
            <CheckboxGroup value={state.checkedIdList}>
              <>
                {state.filterCheckList.map((item, index) => {
                  return (
                    <Checkbox
                      key={index}
                      onChange={_onChangeCheck}
                      value={item.id}
                      style={{
                        display: 'flex',
                        alignItems: 'center',
                        marginLeft: 0,
                        padding: '8px 2px 8px 15px',
                      }}
                      className={style.CheckboxItem}
                      disabled={defaultFlag || defuatChcek(item)}
                    >
                      <div>{item.name}</div>
                      <div>{item.applicationName}</div>
                    </Checkbox>
                  );
                })}
              </>
            </CheckboxGroup>
          </div>
          <div className={style.echoContent}>
            <div className={style.commonInput}>
              <Input
                placeholder="搜索"
                value={checkEcho}
                onChange={(e) => setCheckEcho(e.target.value)}
                suffix={<SearchOutlined style={{ fontSize: 14 }} />}
                allowClear
              />
            </div>
            <div className={style.emptyEdit}>
              <span>
                已选
                {_.filter(
                  state.checkedSecondMenuList,
                  (_v) => _v.operationType !== operation_Type['delete'],
                )?.length || 0}
                项
              </span>
              {defaultFlag ? null : (
                <span onClick={handleEmpty} className={style.empty}>
                  清空
                </span>
              )}
            </div>
            <div
              style={{
                width: '100%',
                flex: 1,
                boxSizing: 'border-box',
                overflow: 'hidden',
                position: 'relative',
              }}
            >
              {state.filterCheckMenuList?.length ? (
                <>
                  {defaultFlag ? (
                    <Table
                      locale={tableLocale}
                      showHeader={false}
                      pagination={false}
                      columns={columns}
                      dataSource={state.filterCheckMenuList}
                      className={style.rowTableStyle}
                      scroll={{
                        y: echoType === 'secMenu' ? 220 : 305,
                      }}
                    />
                  ) : (
                    <DndProvider backend={HTML5Backend}>
                      <Table
                        locale={tableLocale}
                        showHeader={false}
                        pagination={false}
                        columns={columns}
                        dataSource={state.filterCheckMenuList}
                        components={components}
                        className={style.rowTableStyle}
                        onRow={(_, index) => ({
                          index,
                          moveRow,
                        })}
                        scroll={{
                          y: echoType === 'secMenu' ? 220 : 305,
                        }}
                      />
                    </DndProvider>
                  )}
                </>
              ) : (
                <TRDefault type="emptysm" />
              )}
            </div>
          </div>
        </div>
      </Spin>
    );
  },
);
